package org.budo.aliyun.sdk.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.budo.aliyun.sdk.BudoAliyunEcsSdk;
import org.budo.aliyun.sdk.BudoAliyunRegion;
import org.budo.aliyun.sdk.impl.response.DescribeInstancesResponse;
import org.budo.aliyun.sdk.impl.response.DescribeInstancesResponse.Instance;
import org.budo.aliyun.sdk.impl.response.RebootInstanceResponse;
import org.budo.support.assertion.Assert;
import org.budo.support.http.client.Response;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 云服务器
 * @author lmw
 */
public class BudoAliyunEcsSdkImpl extends AbstractBudoAliyunEcsSdk implements BudoAliyunEcsSdk {
    private static final Logger log = Slf4j.getLogger();

    @Override
    public RebootInstanceResponse rebootInstance(String instanceId, Boolean forceStop) {
        Assert.notEmpty(instanceId, "instanceId can not be empty");
        Assert.notNull(forceStop, "forceStop can not be null");

        Map<String, Object> parameters = this.commonParameters();
        parameters.put("Action", ACTION_REBOOT_INSTANCE);

        parameters.put("InstanceId", instanceId);
        parameters.put("ForceStop", forceStop);

        Response response = this.doRequest(parameters);
        if (response.getStatus() > 200) {
            log.error("rebootInstance error, response=" + (null == response ? response : response.toSimpleString()));
            return new RebootInstanceResponse();
        }

        log.info("rebootInstance, response=" + (null == response ? response : response.toSimpleString()));
        return new RebootInstanceResponse();
    }

    @Override
    public DescribeInstancesResponse describeInstances(BudoAliyunRegion region, String[] instanceIds) {
        Assert.notNull(region, "region can not be null");

        Map<String, Object> parameters = this.commonParameters();
        parameters.put("Action", ACTION_DESCRIBE_INSTANCES);

        parameters.put("RegionId", region.getId());
        if (null != instanceIds && instanceIds.length > 0) {
            parameters.put("InstanceIds", JSON.toJSONString(instanceIds));
        }

        Response response = this.doRequest(parameters);
        log.info("describeInstances, response=" + (null == response ? response : response.toSimpleString()));

        List<Instance> instanceList = new ArrayList<Instance>();

        JSONObject jsonObject = this.responseJsonObject(response);
        JSONObject instances = jsonObject.getJSONObject("Instances");
        JSONArray instance = instances.getJSONArray("Instance");
        for (Object eachInstance : instance) {
            JSONObject instanceJsonObject = (JSONObject) eachInstance;

            Instance instanceEntity = new Instance();

            instanceEntity.setInstanceName(instanceJsonObject.getString("InstanceName"));

            List<String> primaryIpAddresses = new ArrayList<String>();

            JSONObject networkInterfaces = instanceJsonObject.getJSONObject("NetworkInterfaces");
            JSONArray networkInterface = networkInterfaces.getJSONArray("NetworkInterface");
            for (Object eachNetworkInterface : networkInterface) {
                JSONObject networkInterfaceJsonObject = (JSONObject) eachNetworkInterface;
                String primaryIpAddress = networkInterfaceJsonObject.getString("PrimaryIpAddress");
                primaryIpAddresses.add(primaryIpAddress);
            }

            instanceEntity.setPrimaryIpAddresses(primaryIpAddresses);
            instanceList.add(instanceEntity);
        }

        DescribeInstancesResponse describeInstancesResponse = new DescribeInstancesResponse();
        describeInstancesResponse.setInstances(instanceList);
        return describeInstancesResponse;
    }
}